package Presentation;

import Metier.Controleurs.GestionVitrine;
import Metier.Objets.LotVitrine;
import Metier.Objets.ModePaiement;
import Metier.Objets.Produit;
import Metier.Objets.Stock;
import Metier.Objets.TypeProduit;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.SpinnerNumberModel;

public class OngletVendeur extends Onglet {

    private JScrollPane scrollListePrincipale;
    private JScrollPane scrollTableProduit;
    private JScrollPane scrollTableCommande;

    private JList listePrincipale;

    private JPanel panelGeneral;
    private JPanel panelProduit;
    private JPanel panelCommande;
    private JPanel panelTableCommande;
    private JPanel panelTableCommandeTotale;
    private JPanel panelBoutons;

    private JTable tableProduit;
    private JTable tableCommande;
    private final DefaultTableModel tableCommandeModel;

    private JLabel lblTotal;

    private JButton btnBoisson;

    private final GestionVitrine gVitrine;

    private List<LotVitrine> listLotVitrine;
    private List<Produit> listAlertes;
    private List<Produit> listAlertesBoissons;

    private final ResourceBundle venteBundle;

    private final OngletVendeur that;

    /**
     * 
     * @param fp 
     */
    public OngletVendeur(FenetrePrincipale fp) {
        super(fp);
        this.that = this;
        this.gVitrine = new GestionVitrine(this);
        this.listLotVitrine = new ArrayList<>();
        this.listAlertes = new ArrayList<>();
        this.listAlertesBoissons = new ArrayList<>();
        this.venteBundle = ResourceBundle.getBundle("ressources/Vente/Vente", fp.getLocale());
        this.tableCommandeModel = new DefaultTableModel();
        this.tableCommandeModel.addColumn(this.venteBundle.getString("vente.produit"));
        this.tableCommandeModel.addColumn(this.venteBundle.getString("vente.quantite"));
        this.tableCommandeModel.addColumn(this.venteBundle.getString("vente.prixunite"));
        this.tableCommandeModel.addColumn("id");
        this.tableCommandeModel.addColumn(this.venteBundle.getString("vente.retirer"));
        this.tableCommandeModel.addColumn(this.venteBundle.getString("vente.produit"));
        initComponents();
    }

    /**
     * 
     */
    private void initComponents() {
        /**
         * LINE_START
         */
        this.listePrincipale = new JList(this.gVitrine.getContenuListPrincipale());
        this.listePrincipale.setSelectedIndex(0);
        this.listePrincipale.setFixedCellHeight(30);
        this.listePrincipale.setSelectedIndex(0);
        this.listePrincipale.addListSelectionListener((ListSelectionEvent e) -> {
            if (e.getValueIsAdjusting()) {
                if (((JList) e.getSource()).getSelectedValue() != null) {
                    switchProduit((Produit) ((JList) e.getSource()).getSelectedValue());
                }
            }
        });
        this.listePrincipale.setCellRenderer(new ListePrincipaleVendeurCellRender(this));
        this.scrollListePrincipale = new JScrollPane(this.listePrincipale);
        this.add(this.scrollListePrincipale, BorderLayout.LINE_START);

        /**
         * CENTER
         */
        this.panelGeneral = new JPanel(new GridLayout(1, 2));

        this.panelProduit = new JPanel(new BorderLayout());
        this.tableProduit = new JTable();
        this.tableProduit.setRowHeight(20);
        this.tableProduit.setSelectionBackground(this.tableProduit.getBackground());
        this.tableProduit.setSelectionForeground(this.tableProduit.getForeground());
        this.tableProduit.setModel(gVitrine.getTableProduitModel((Produit) this.getListePrincipale().getSelectedValue(), this.listLotVitrine));
        this.tableProduit.removeColumn(this.tableProduit.getColumnModel().getColumn(5));
        this.scrollTableProduit = new JScrollPane(this.tableProduit);
        this.panelProduit.add(this.scrollTableProduit, BorderLayout.CENTER);
        this.btnBoisson = new JButton("Ajouter boisson");
        this.btnBoisson.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JPanel panel = new JPanel(new BorderLayout());
                JPanel subPanel = new JPanel(new GridLayout(1, 2));
                Produit p = (Produit)listePrincipale.getSelectedValue();
                DefaultTableModel tm = gVitrine.getTableStockModel(p);
                JTable tableStocks = new JTable(tm);
                DefaultTableCellRenderer rightRenderer = new DefaultTableCellRenderer();
                rightRenderer.setHorizontalAlignment(JLabel.RIGHT);
                tableStocks.getColumnModel().getColumn(0).setCellRenderer(rightRenderer);
                tableStocks.getColumnModel().getColumn(1).setCellRenderer(rightRenderer);
                tableStocks.removeColumn(tableStocks.getColumnModel().getColumn(3));
                tableStocks.removeColumn(tableStocks.getColumnModel().getColumn(2));
                JScrollPane scrollPane = new JScrollPane(tableStocks);
                tableStocks.setPreferredSize(new Dimension(300, 300));
                JLabel label = new JLabel(venteBundle.getString("vente.quantite"));
                JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, 0, 1));
                ListSelectionModel listSelectionModel = tableStocks.getSelectionModel();
                listSelectionModel.addListSelectionListener(new ListSelectionListener() {
                    @Override
                    public void valueChanged(ListSelectionEvent e) {
                        int row = ((DefaultListSelectionModel)e.getSource()).getMinSelectionIndex();
                        ((SpinnerNumberModel)spinner.getModel()).setMaximum((int)tm.getValueAt(row, 1));
                    }
                });
                subPanel.add(label);
                subPanel.add(spinner);
                panel.add(scrollPane, BorderLayout.CENTER);
                panel.add(subPanel, BorderLayout.PAGE_END);
                int choice = JOptionPane.showConfirmDialog(getFP(),
                        panel,
                        venteBundle.getString("vente.ajouterboisson"),
                        JOptionPane.OK_CANCEL_OPTION,
                        JOptionPane.PLAIN_MESSAGE);
                int val = (int)spinner.getValue();
                if(choice == JOptionPane.OK_OPTION && val > 0){
                    Date d = (Date)tm.getValueAt(tableStocks.getSelectedRow(), 3);
                    Stock s = (Stock)tm.getValueAt(tableStocks.getSelectedRow(), 2);
                    gVitrine.ajouterBoissonVitrine(p, val, d, s);
                    rafraichir();
                }
            }
        });
        this.btnBoisson.setVisible(false);
        this.panelProduit.add(this.btnBoisson, BorderLayout.PAGE_END);
        this.panelGeneral.add(this.panelProduit);

        this.panelCommande = new JPanel(new BorderLayout());
        this.panelCommande.setBorder(BorderFactory.createTitledBorder(this.venteBundle.getString("vente.commandeencours")));
        this.panelTableCommande = new JPanel(new BorderLayout());
        this.tableCommande = new JTable();
        this.tableCommande.setRowHeight(20);
        this.tableCommande.setModel(this.tableCommandeModel);
        this.tableCommande.setSelectionBackground(this.tableCommande.getBackground());
        this.tableCommande.setSelectionForeground(this.tableCommande.getForeground());
        this.tableCommande.removeColumn(this.tableCommande.getColumnModel().getColumn(5));
        this.tableCommande.removeColumn(this.tableCommande.getColumnModel().getColumn(3));
        Action retirer = new AbstractAction(){
            @Override
            public void actionPerformed(ActionEvent e){
                int row = ((JTable)e.getSource()).getSelectedRow();
                int max = (int)tableCommandeModel.getValueAt(row, 1);
                int choice = JOptionPane.OK_OPTION;
                int val = max;
                if (max > 1) {
                    JPanel panel = new JPanel(new GridLayout(1, 2));
                    JSpinner spinner = new JSpinner(new SpinnerNumberModel(1, 1, max, 1));
                    JLabel label = new JLabel(venteBundle.getString("vente.quantite") + " : ");
                    panel.add(label);
                    panel.add(spinner);
                    choice = JOptionPane.showConfirmDialog(getFP(),
                            panel,
                            venteBundle.getString("vente.commander"),
                            JOptionPane.OK_CANCEL_OPTION,
                            JOptionPane.PLAIN_MESSAGE);
                    val = (int)spinner.getValue();
                }
                if(choice == JOptionPane.OK_OPTION && val > 0){
                    LotVitrine lot = gVitrine.getLot((int)tableCommandeModel.getValueAt(row, 3));
                    lot.setQuantite(lot.getQuantite() + val);
                    gVitrine.modifierLot(lot);
                    if (val == max) {
                        tableCommandeModel.removeRow(row);
                    } else {
                        tableCommandeModel.setValueAt(max-val, row, 1);
                    }
                    lblTotal.setText(String.valueOf(getTotalPrice()));
                    rafraichir();
                }
            }
        };
        ButtonColumn bc = new ButtonColumn(this.tableCommande, retirer, 3);
        bc.setMnemonic(KeyEvent.VK_D);
        this.scrollTableCommande = new JScrollPane(this.tableCommande);
        this.panelTableCommande.add(this.scrollTableCommande, BorderLayout.CENTER);
        this.panelTableCommandeTotale = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        this.panelTableCommandeTotale.add(new JLabel(this.venteBundle.getString("vente.total") + " : "));
        this.lblTotal = new JLabel("0");
        this.panelTableCommandeTotale.add(this.lblTotal);
        this.panelTableCommande.add(this.panelTableCommandeTotale, BorderLayout.PAGE_END);
        this.panelCommande.add(this.panelTableCommande, BorderLayout.CENTER);

        this.panelBoutons = new JPanel(new GridBagLayout());
        JButton valider = new JButton(this.venteBundle.getString("vente.validercommande"));
        valider.setForeground(Color.white);
        valider.setBackground(Color.decode("#4caf50"));
        valider.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JPanel panel = new JPanel(new GridLayout(1, 2));
                JComboBox cb = new JComboBox(new DefaultComboBoxModel<>(ModePaiement.values()));
                JLabel label = new JLabel(venteBundle.getString("vente.modepaiement") + " : ");
                panel.add(label);
                panel.add(cb);
                int choice = JOptionPane.showConfirmDialog(getFP(),
                        panel,
                        venteBundle.getString("vente.modepaiement"),
                        JOptionPane.OK_CANCEL_OPTION,
                        JOptionPane.PLAIN_MESSAGE);
                if(choice == JOptionPane.OK_OPTION){
                    gVitrine.validerCommande((ModePaiement)cb.getSelectedItem());
                }
            }
        });
        JButton annuler = new JButton(this.venteBundle.getString("vente.annulercommande"));
        annuler.setForeground(Color.white);
        annuler.setBackground(Color.decode("#e53935"));
        annuler.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int nb = tableCommandeModel.getRowCount();
                for (int i = 0; i < nb; i++) {
                    int id = (int)tableCommandeModel.getValueAt(0, 3);
                    LotVitrine lot = gVitrine.getLot(id);
                    lot.setQuantite(lot.getQuantite() + (int)tableCommandeModel.getValueAt(0, 1));
                    gVitrine.modifierLot(lot);
                    tableCommandeModel.removeRow(0);
                }
                lblTotal.setText("0");
                rafraichir();
            }
        });
        GridBagConstraints gbc = new GridBagConstraints(0, 0,
                1, 1,
                0, 0,
                GridBagConstraints.LINE_END,
                GridBagConstraints.NONE,
                new Insets(5, 10, 5, 10),
                0, 0
        );
        this.panelBoutons.add(valider, gbc);
        gbc.gridx = 1;
        this.panelBoutons.add(annuler, gbc);
        this.panelCommande.add(this.panelBoutons, BorderLayout.PAGE_END);

        this.panelGeneral.add(this.panelCommande);
        this.add(this.panelGeneral, BorderLayout.CENTER);

        javax.swing.Timer timerAlertes = new javax.swing.Timer(10000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ThreadRafraichissementVitrine thread = new ThreadRafraichissementVitrine(that);
                thread.start();
            }
        });
        timerAlertes.start();

        this.rafraichir();
    }

    /**
     * 
     * @param p 
     */
    public void switchProduit(Produit p) {
        if (p != null) {
            if (p.getType() == TypeProduit.BOISSON) {
                this.btnBoisson.setVisible(true);
            } else {
                this.btnBoisson.setVisible(false);
            }
            this.tableProduit.setModel(this.gVitrine.getTableProduitModel(p, this.listLotVitrine));
            this.tableProduit.removeColumn(this.tableProduit.getColumnModel().getColumn(5));
            ((AbstractTableModel) this.tableProduit.getModel()).fireTableDataChanged();
            Action commanderProduit = new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int row = ((JTable) e.getSource()).getSelectedRow();
                    LotVitrine lot = gVitrine.getLot(Integer.valueOf(that.getTableProduit().getModel().getValueAt(row, 5).toString()));
                    JPanel panel = new JPanel(new GridLayout(1, 2));
                    int max = lot.getQuantite();
                    int choice = JOptionPane.OK_OPTION;
                    int val = max;
                    if (max > 1) {
                        JSpinner spinner = new JSpinner(new SpinnerNumberModel(1, 1, max, 1));
                        JLabel label = new JLabel(venteBundle.getString("vente.quantite") + " : ");
                        panel.add(label);
                        panel.add(spinner);
                        choice = JOptionPane.showConfirmDialog(getFP(),
                                panel,
                                venteBundle.getString("vente.commander"),
                                JOptionPane.OK_CANCEL_OPTION,
                                JOptionPane.PLAIN_MESSAGE);
                        val = (int) spinner.getValue();
                    }
                    if (choice == JOptionPane.OK_OPTION && val > 0) {
                        gVitrine.retirerProduit(lot, val);
                        rafraichir();
                        Object[] rowdata = new Object[6];
                        rowdata[0] = lot.getProduit();
                        rowdata[1] = val;
                        rowdata[2] = lot.getProduit().getPrix();
                        rowdata[3] = lot.getId();
                        rowdata[4] = venteBundle.getString("vente.retirer");
                        rowdata[5] = lot.getProduit();
                        that.getTableCommandeModel().addRow(rowdata);
                        lblTotal.setText(String.valueOf(getTotalPrice()));
                    }
                }
            };
            Action jeterLot = new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int row = ((JTable) e.getSource()).getSelectedRow();
                    int choice = JOptionPane.showConfirmDialog(that,
                            venteBundle.getString("vente.confirmationjeter"),
                            venteBundle.getString("vente.confirmation"),
                            JOptionPane.YES_NO_OPTION);
                    if (choice == JOptionPane.YES_OPTION) {
                        gVitrine.jeterLot(Integer.valueOf(that.getTableProduit().getModel().getValueAt(row, 5).toString()));
                        JOptionPane.showMessageDialog(that,
                                venteBundle.getString("vente.confirmationjeterok"),
                                venteBundle.getString("vente.confirmation"),
                                JOptionPane.INFORMATION_MESSAGE);
                        that.rafraichir();
                    }
                }
            };
            ButtonColumn buttonColumnBuyProd = new ButtonColumn(this.tableProduit, commanderProduit, 3);
            buttonColumnBuyProd.setMnemonic(KeyEvent.VK_D);
            ButtonColumn buttonColumnSupprProd = new ButtonColumn(this.tableProduit, jeterLot, 4);
            buttonColumnSupprProd.setMnemonic(KeyEvent.VK_D);
        }
    }

    /**
     * 
     * @return 
     */
    public float getTotalPrice() {
        float total = 0;
        for (int i = 0; i < tableCommandeModel.getRowCount(); i++) {
            float price= Float.valueOf(tableCommande.getValueAt(i, 1).toString()) *
                    Float.valueOf(tableCommandeModel.getValueAt(i, 2).toString());
            total += price;
        }
        return total;
    }

    /**
     * 
     * @param p
     * @return 
     */
    public boolean isPerime(Produit p) {
        return this.listAlertes.contains(p);
    }

    /**
     * 
     * @param p
     * @return 
     */
    public boolean isInAlerte(Produit p) {
        return this.listAlertesBoissons.contains(p);
    }

    /**
     * 
     */
    @Override
    public void rafraichir() {
        ThreadRafraichissementVitrine thread = new ThreadRafraichissementVitrine(that);
        thread.start();
    }

    /**
     * 
     */
    @Override
    public void help() {
        String msg = venteBundle.getString("vente.aidemessage");
        JOptionPane.showMessageDialog(this.getFP(),
                msg,
                venteBundle.getString("vente.aide"),
                JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * 
     * @param lm 
     */
    public void setListProduit(ListModel lm) {
        int index = this.listePrincipale.getSelectedIndex();
        this.listePrincipale.setModel(lm);
        this.listePrincipale.setSelectedIndex(index);
    }

    /**
     * 
     * @return 
     */
    public JList getListePrincipale() {
        return listePrincipale;
    }

    /**
     * 
     * @return 
     */
    public JTable getTableProduit() {
        return tableProduit;
    }

    /**
     * 
     * @return 
     */
    public DefaultTableModel getTableCommandeModel() {
        return tableCommandeModel;
    }

    /**
     * 
     * @param listLotVitrine 
     */
    public void setListLotVitrine(java.util.List<LotVitrine> listLotVitrine) {
        this.listLotVitrine = listLotVitrine;
    }

    /**
     * 
     * @return 
     */
    public JLabel getLblTotal() {
        return lblTotal;
    }

    /**
     * 
     * @return 
     */
    public List<Produit> getListAlertes() {
        return listAlertes;
    }

    /**
     * 
     * @param listAlertes 
     */
    public void setListAlertes(List<Produit> listAlertes) {
        this.listAlertes = listAlertes;
    }

    /**
     * 
     * @return 
     */
    public List<Produit> getListAlertesBoissons() {
        return listAlertesBoissons;
    }

    /**
     * 
     * @param listAlertesBoissons 
     */
    public void setListAlertesBoissons(List<Produit> listAlertesBoissons) {
        this.listAlertesBoissons = listAlertesBoissons;
    }
}
